package com.mmall.service;

import com.google.common.base.Preconditions;
import com.mmall.common.ExceptionError;
import com.mmall.common.RequestHolder;
import com.mmall.dao.SysDeptMapper;
import com.mmall.model.SysDept;
import com.mmall.param.DeptParam;
import com.mmall.util.BeanVaildator;
import com.mmall.util.IpUtil;
import com.mmall.util.LevelUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
public class SysDeptService {
    @Resource
    private SysDeptMapper mapper;
    @Resource
    private SysLogService sysLogService;

    public void save(DeptParam param){
        //校验
        BeanVaildator.check(param);
        if (checkExist(param.getParentId(),param.getName(),param.getId())){
            ExceptionError.throwError("同一层级下存在相同名称的部门");
        }
        SysDept dept = SysDept.builder().name(param.getName()).parentId(param.getParentId())
                .seq(param.getSeq()).remark(param.getRemark()).build();
        //设置层级
        dept.setLevel(LevelUtil.calculateLevel( getLevel( param.getParentId()),param.getParentId() ));
        dept.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
        dept.setOperator(RequestHolder.getCurrentUser().getUsername());
        dept.setOperateTime(new Date());

        mapper.insertSelective(dept);
        sysLogService.saveDeptLog(null,dept);
    }

    private boolean checkExist(Integer parentId,String deptName,Integer deptId){
        return mapper.countByNameAndParentId(parentId,deptName,deptId) > 0;
    }

    private String getLevel(Integer deptId){
        //通过parentId查到是否存在上级，如果存在就返回上级的id
        SysDept dept = mapper.selectByPrimaryKey(deptId);
        if (dept == null){
            return null;
        }
        return dept.getLevel();
    }


    public void update(DeptParam param) {
        //校验
        BeanVaildator.check(param);

        SysDept beforeDept = mapper.selectByPrimaryKey(param.getId());
        Preconditions.checkNotNull(beforeDept,"待更新的部门不存在");

        if (checkExist(param.getParentId(),param.getName(),param.getId())){
            ExceptionError.throwError("同一层级下存在相同名称的部门");
        }


        SysDept afterDept = SysDept.builder().id(param.getId()).name(param.getName()).parentId(param.getParentId())
                .seq(param.getSeq()).remark(param.getRemark()).build();
        //设置层级
        afterDept.setLevel(LevelUtil.calculateLevel( getLevel( param.getParentId()),param.getParentId() ));
        afterDept.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
        afterDept.setOperator(RequestHolder.getCurrentUser().getUsername());
        afterDept.setOperateTime(new Date());

        updateWithChild(beforeDept,afterDept);
        sysLogService.saveDeptLog(beforeDept,afterDept);
    }

    /**
     * 更新子部门
     * @param beforeDept
     * @param afterDept
     */
    private void updateWithChild(SysDept beforeDept, SysDept afterDept) {
        //得到新旧层级
        String newLevelPrefix = afterDept.getLevel();
        String oldLevelPrefix = beforeDept.getLevel();
        //判断是否相等
        if (!StringUtils.equals(newLevelPrefix,oldLevelPrefix)){
            //不等就要更新
            //首先拼接一个当前部门的子部门的层级
            String childLevel = oldLevelPrefix+LevelUtil.SEPARATOR+afterDept.getId();

            //获取该部门以下所有子部门信息

            List<SysDept> deptList = mapper.getChildDeptListByLevel(childLevel);
            if (CollectionUtils.isNotEmpty(deptList)){
               for (SysDept dept : deptList){
                   String level = dept.getLevel();
                   //如果旧层级和子部门的层级前部不能对应就不做截取拼接
                   if (level.indexOf(oldLevelPrefix)==0){
                       //如果发生改变则拆分拼接
                       level = newLevelPrefix + level.substring(oldLevelPrefix.length());
                       dept.setLevel(level);
                   }
               }
               mapper.batchUpdateLevel(deptList);
            }
        }
        mapper.updateByPrimaryKey(afterDept);
    }

    /**
     * 删除
     * @param id
     */
    public void delete(Integer id) {
        SysDept dept = mapper.selectByPrimaryKey(id);
        Preconditions.checkNotNull(dept,"待删除的部门不存在，无法删除");
        //首先拼接一个当前部门的子部门的层级
        String childLevel = dept.getLevel()+LevelUtil.SEPARATOR+dept.getId();
        //获取该部门以下所有子部门信息
        if (CollectionUtils.isNotEmpty(mapper.getChildDeptListByLevel(childLevel))){
           ExceptionError.throwError("当前部门下面有子部门，无法删除");
        }
        mapper.deleteByPrimaryKey(id);
        sysLogService.saveDeptLog(dept,null);
    }
}
